﻿using System;
using System.Linq;
using System.Reflection;
using CompactMapper.Orm.Annotations;

namespace CompactMapper.Orm.UnitOfWork.Mappings.Meta.PropertyInfos.Relations
{
    internal abstract class Relation : PropertyInfoMeta
    {
        private readonly String _somethingToManyTableName;

        protected Relation(PropertyInfo propertyInfo)
            : base(propertyInfo)
        {
            var type = propertyInfo.PropertyType.GetGenericArguments().FirstOrDefault();
            _somethingToManyTableName = type != null ? type.Name : null;
        }

        public abstract String TableName { get; }

        public static Relation From(PropertyInfoPersistenceAttributePair pair)
        {
            if (pair.PersistenceAttribute is SingleAttribute)
                return new Single(pair);

            if (pair.PersistenceAttribute is HasAndBelongsToManyAttribute)
                return new HasAndBelongsToMany(pair);

            if (pair.PersistenceAttribute is HasManyAttribute)
                return new HasMany(pair);

            throw new InvalidOperationException(String.Format("propertyInfo {0} has no relation attribute",
                                                              pair.PropertyInfo));
        }

        protected String GetSomethingToManyTableName()
        {
            return _somethingToManyTableName;
        }
    }
}